package com.test.design;



/**
 * 
 * @author chenj
 * @desc future 模式 , 使用场景, 针对构建需要很长的时间,所以单独使用线程构建,同时返回一个包装数据,  而主线程做其他的任务, 当构建完以后自动装配包装数据, 形成
 * 真实场景数据
 *
 */
public class FutureDesign {

	public static void main(String[] args) throws Exception {
		Client client = new Client();
		Data data = client.request("111111111");
		System.out.println("result:"+data.getResult() );
	}
}

class Client {
	public Data request(final String querystr) throws InterruptedException {
		FutureData future = new FutureData();
		new Thread() {// real
			 @Override
			    public void run() {
				 System.out.println(".....");
				  RealData realData = new RealData(querystr);
				  future.setRealData(realData);
			    }
		}.start();
		System.out.println("我在做其它的事情.......");
		Thread.sleep(100);
		return future;
	}
}

interface Data {
	/** 等待 realData构造完成 */
	public String getResult();
}
interface Future {
	public void setRealData(RealData realData);
}

/** futureData 快速返回一个realData 的包装 */
class FutureData implements Data, Future {
	protected RealData realData = null; // futureData 是realData的包装
	protected boolean isReady = false; //

	@Override
	public synchronized String getResult() {
		if (!isReady) {
			try {
				wait(); // 一直等到setRealData的注入
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		return realData.getResult(); // 由realData 实现
	}

	@Override
	public synchronized void setRealData(RealData realData) {
		if (isReady) {
			return;
		}
		isReady = true;
		this.realData = realData;
		notifyAll();
	}

}

class RealData implements Data {
	protected String result = null;

	public RealData(String param) {
		/** 构造真实的数据 可能话费时间比较长 */
		System.out.println("param is:" + param);
		try {
			Thread.sleep(5000);
			result = "这就是你要的结果, 真实数据";
		} catch (Exception e) {
		}
	}

	@Override
	public String getResult() {
		// TODO Auto-generated method stub
		return result;
	}

}